In [1]:
    
from __future__ import print_function # 2.7 compatability
from IPython.html import widgets # Widget definitions
from IPython.display import display # Used to display widgets in the notebook
    
As mentioned in Part 1, the widget attributes are IPython traitlets.  Traitlets are eventful.  To handle  changes, the on_trait_change method of the widget can be used to register a callback.  The docstring for on_trait_change can be seen below.  Both the name and remove properties are optional.
In [2]:
    
print(widgets.Widget.on_trait_change.__doc__)
    
    
Mentioned in the doc string, the callback registered can have 4 possible signatures:
Using this method, an example of how to output an IntSliderWiget's value as it is changed can be seen below.
In [3]:
    
int_range = widgets.IntSliderWidget()
display(int_range)
def on_value_change(name, value):
    print(value)
int_range.on_trait_change(on_value_change, 'value')
    
The ButtonWidget is a special widget, like the ContainerWidget and TabWidget, that isn't used to represent a data type.  Instead the button widget is used to handle mouse clicks.  The on_click method of the ButtonWidget can be used to register function to be called when the button is clicked.  The docstring of the on_click can be seen below.
In [4]:
    
print(widgets.ButtonWidget.on_click.__doc__)
    
    
Button clicks are transmitted from the front-end to the back-end using custom messages.  By using the on_click method, a button that prints a message when it has been clicked is shown below.
In [5]:
    
button = widgets.ButtonWidget(description="Click Me!")
display(button)
def on_button_clicked(b):
    print("Button clicked.")
button.on_click(on_button_clicked)
    
    
Event handlers can also be used to create widgets. In the example below, clicking a button spawns another button with a description equal to how many times the parent button had been clicked at the time.
In [6]:
    
def new_button(clicked):
    button = widgets.ButtonWidget()
    button.clicks = 0
    clicked.clicks += 1
    button.description = "%d" % clicked.clicks
    display(button)
    button.on_click(new_button)
button = widgets.ButtonWidget(description = "Start")
button.clicks = 0
display(button)
button.on_click(new_button)